package com.yxplearn.mybatisplus.manager;

import java.util.List;

/**
 * 缓存管理器,多线程下可安全使用
 *
 * @author xiezuojie
 */
public final class MemoryCacheManager implements EntityCacheManager {

//    LRUCache<Integer, Entities> c = new LRUCache<>(CoreConfig.intValue("CachedPlayerNums"));
    LRUCache<Long, Entities> c = new LRUCache<>(100);

    public MemoryCacheManager() {
        c.setListener((v) -> {
            Entities en = (Entities) v;
            CachedDataPersistService.addToUnsavedQueue(en);
        });
    }

    @Override
    public <T extends PersistEntity> boolean hasEntity(long playerId, Class<T> clazz) {
        Entities en = c.get(playerId);
        if (en == null) {
            return false;    //不存在实体直接返回false
        }
        return en.hasEntity(clazz);
    }

    /**
     * @param playerId
     * @param clazz
     * @return 缓存实体, 当从缓存获取的实体为null时, 会执行{@link CachedDataManager#initCache(int)}加载缓存并返回.
     */
    public <T extends PersistEntity> T getEntity(long playerId, Class<T> clazz) {
        Entities en = getEntities(playerId);
        return en.getEntity(clazz);
    }

    public <T extends PersistEntity> T getEntityFromCache(long playerId, Class<T> clazz) {
        Entities en = getEntitiesIfExisting(playerId);
        if (en != null) {
            return en.getEntityFromCache(clazz);
        } else {
            return null;
        }
    }

    /**
     * @param playerId
     * @return 缓存实体集合
     */
    public Entities getEntities(long playerId) {
        Entities en = c.get(playerId);
        if (en == null) {
            synchronized (this) {
                en = CachedDataPersistService.takeFromUnsavedQueue(playerId);
                if (en == null) {
                    en = new Entities(playerId);
                }
                Entities old = c.putIfAbsent(playerId, en);
                if (old != null) {
                    en = old;
                }
            }
        }
        return en;
    }

    @Override
    public Entities getEntitiesIfExisting(long playerId) {
        Entities en = c.get(playerId);
        return en;
    }

    @Override
    public List<Entities> getAllEntities() {
        return c.getAll();
    }

    @Override
    public Entities remove(long playerId) {
        Entities en = c.remove(playerId);
        if (en != null) {
            CachedDataPersistService.addToUnsavedQueue(en);
        }
        return en;
    }

}
